package com.zw.a.basic.a15.demo03_reflect;

import com.itheima.pojo.Student;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//案例: 通过反射获取成员方法并调用
/*
    Method 单词的意思就是: 方法

    反射获取成员方法涉及到的API, 以下全部都是Class类中的方法
        public Method getDeclaredMethod(String name, Class... params);  根据传入的方法名, 获取其对应的成员方法对象(包括私有)

    Method 类中的成员方法:
        public Object invoke(Object obj, Object... args)        执行指定对象(obj)的指定方法(method).

    获取成员方法的目的:
       就是为了调用该方法, 且反射能越过泛型检查, 一些在编译期搞不定的事儿挪到运行时就可以搞定.
 */
public class Demo08 {
    public static void main(String[] args) throws Exception{
        //需求1: 调用Student#show2()方法.  通过反射获取私有的成员方法并调用
        //method01();


        //需求2: 调用Student#getSum()方法.  通过反射获取公共的成员方法并调用
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");
        //2. 获取指定的成员方法
        Method method = clazz.getDeclaredMethod("getSum",int.class,int.class);
        //3. 获取学生类的对象.
        Student s = (Student)clazz.newInstance();
        //4. 调用s对象的show2()方法
        int sum = (int)method.invoke(s, 10, 20);
        System.out.println("sum: " + sum);
    }

    public static void method01() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //1. 获取该类的字节码文件对象.
        Class<?> clazz = Class.forName("com.itheima.pojo.Student");
        //2. 获取指定的成员方法
        Method method = clazz.getDeclaredMethod("show2");
        //3. 获取学生类的对象.
        Student s = (Student)clazz.newInstance();
        //4. 核心: 暴力反射
        method.setAccessible(true);
        //5. 调用s对象的show2()方法
        method.invoke(s);
    }
}
